package com.clss.commandhelper.function.videoroom;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.media.AudioManager;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.clss.commandhelper.CommandHelperApplication;
import com.clss.commandhelper.R;
import com.clss.commandhelper.base.BaseActivity;
import com.clss.commandhelper.function.home.UploadLocationService;
import com.clss.commandhelper.tools.AMapUtil;
import com.clss.commandhelper.tools.Constant;
import com.clss.commandhelper.tools.Lg;
import com.clss.commandhelper.tools.SpHelper;
import com.clss.commandhelper.tools.UploadHelper;
import com.clss.commandhelper.tools.Utils;
import com.clss.commandhelper.tools.VersionUpdataHelper;
import com.clss.commandhelper.tools.eventbus.EventBusHelper;
import com.clss.commandhelper.tools.eventbus.EventBusMessage;
import com.clss.commandhelper.tools.janus.entity.MediaSessionBean;
import com.clss.commandhelper.tools.janus.plugin.VideoRoomPlugin;

import org.greenrobot.eventbus.Subscribe;
import org.webrtc.VideoRendererGui;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * 视频报警
 * @author liuv
 */

public class WebRtcActivity extends BaseActivity implements WebRtcPresenter.WebRtcView,
        AMap.OnMyLocationChangeListener{

    private static final String TAG = "WebRtcActivity";

    public static final String DISPLAY_ID = "DISPLAY_ID";

    @BindView(R.id.web_rtc_video_glsv)
    GLSurfaceView webRtcVideoGLSurfaceView;
    @BindView(R.id.web_rtc_chat_list_lv)
    ListView webRtcChatListLv;
    @BindView(R.id.web_rtc_stop_video_iv)
    ImageView webRtcStopVideoIv;
    @BindView(R.id.web_rtc_chat_add_iv)
    ImageView webRtcChatAddIv;
    @BindView(R.id.web_rtc_chat_et)
    EditText webRtcChatEt;
    @BindView(R.id.web_rtc_chat_send_btn)
    Button webRtcChatSendBtn;
    @BindView(R.id.web_rtc_case_place_et)
    EditText webRtcCasePlaceEt;
    @BindView(R.id.web_rtc_case_place_ll)
    LinearLayout webRtcCasePlaceLl;
    @BindView(R.id.web_rtc_map)
    TextureMapView webRtcMap;
    @BindView(R.id.web_rtc_case_place_iv)
    ImageView webRtcChooseEventTypeLl;
    @BindView(R.id.web_rtc_switch_camera_iv)
    ImageView webRtcSwitchCameraIv;

    private WebRtcPresenter mWebRtcPresenter;

    private MediaSessionBean mMediaSessionBean;
    private VideoRoomPlugin mVideoRoomPlugin;
    private String mSendLastMsg;
    private List<ChatMsgTextEntity> mChatMsgTextEntityList;
    private ChatListAdapter mChatListAdapter;
    private boolean mUnPublished;
    private AudioManager mAudioManager;

    private String mId;
    private boolean mIsTest;
    private String mVideoType;
    private String mDisplayId;

    private AMap mAMap;
    private GeocodeSearch mGeocoderSearch;
    private double mLat;
    private double mLng;
    private int mUploadLatlngAble = 0;

    private CreateChatEntity mCreateChatEntity;
//    private ChatRoomPresenter mChatRoomPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected int setViewId() {
        return R.layout.activity_web_rtc;
    }

    @Override
    protected void initView() {

        Bundle bundle = getIntent().getExtras();
        mMediaSessionBean = (MediaSessionBean) bundle.getSerializable(Constant.VIDEO_CASE_INFO);
        mDisplayId = bundle.getString(DISPLAY_ID);

        mChatMsgTextEntityList = new ArrayList<>();
        mChatListAdapter = new ChatListAdapter(this, 0);
        webRtcChatListLv.setAdapter(mChatListAdapter);

        webRtcChatListLv.setOnItemClickListener((parent, view, position, id) -> webRtcChatListLv.setVisibility(View.INVISIBLE));
    }

    @Override
    protected void initData(@Nullable Bundle savedInstanceState) {
        mWebRtcPresenter = new WebRtcPresenter(WebRtcPresenter.CHAT_TYPE_CALL);
        mWebRtcPresenter.setmWebRtcView(this);

//        mChatRoomPresenter = new ChatRoomPresenter();
//        mChatRoomPresenter.setmChatRoomView(this);

        Utils.openSpeaker(this);
        mAudioManager = (AudioManager) getSystemService(Service.AUDIO_SERVICE);

        if (mMediaSessionBean != null) {
            mCreateChatEntity = mWebRtcPresenter.createChat(mMediaSessionBean, mIsTest);
        }

        initMap(savedInstanceState);
        initVideoRoom();
        mWebRtcPresenter.reconnectChat(mMediaSessionBean.getId());
    }

    private void initVideoRoom() {

        Lg.i(TAG, "---initVideoRoom===");
        webRtcVideoGLSurfaceView.setPreserveEGLContextOnPause(true);
        webRtcVideoGLSurfaceView.setKeepScreenOn(true);
        VideoRendererGui.setView(webRtcVideoGLSurfaceView, () -> startCall());
        mVideoRoomPlugin = new VideoRoomPlugin(mMediaSessionBean);
    }

    private void initMap(@Nullable Bundle savedInstanceState) {
        webRtcMap.onCreate(savedInstanceState);
        mAMap = webRtcMap.getMap();

        AMapLocation location = CommandHelperApplication.getMapLocation();
        if (null == location || location.getLatitude() < 1){
            return;
        }
        mLat = location.getLatitude();
        mLng = location.getLongitude();
        webRtcCasePlaceEt.setText(location.getAddress());

        CameraUpdate mCameraUpdate = CameraUpdateFactory
                .newCameraPosition(new CameraPosition(new LatLng(location.getLatitude(), location.getLongitude()), 15, 0, 0));
        mAMap.moveCamera(mCameraUpdate);

        mAMap.setOnMyLocationChangeListener(this);

        final Marker regeoMarker = mAMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
                .icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        regeoMarker.setTitle(getString(R.string.case_place));
        regeoMarker.setPosition(new LatLng(location.getLatitude(), location.getLongitude()));
        regeoMarker.showInfoWindow();

        mAMap.setOnMarkerClickListener(marker -> {
            marker.showInfoWindow();
            return false;
        });

        mAMap.setOnMapClickListener(latLng -> {
            LatLonPoint latLonPoint = AMapUtil.convertToLatLonPoint(latLng);
            mLat = latLng.latitude;
            mLng = latLng.longitude;
            regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
            RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 50,
                    GeocodeSearch.AMAP);
            mGeocoderSearch.getFromLocationAsyn(query);

        });

        mGeocoderSearch = new GeocodeSearch(this);
        mGeocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                webRtcCasePlaceEt.setText(regeocodeResult.getRegeocodeAddress().getFormatAddress());
            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
            }
        });

        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.interval(10000);
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.gps_point));
        mAMap.setMyLocationStyle(myLocationStyle);
        mAMap.setMyLocationEnabled(true);

    }

    @OnClick({R.id.web_rtc_stop_video_iv, R.id.web_rtc_chat_add_iv, R.id.web_rtc_chat_send_btn,
            R.id.web_rtc_video_glsv, R.id.web_rtc_case_place_ll, R.id.web_rtc_case_place_iv,
            R.id.web_rtc_switch_camera_iv})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.web_rtc_stop_video_iv:
                showExitDialog();
                break;
            case R.id.web_rtc_chat_add_iv:
                chooseLocalImage();
                break;
            case R.id.web_rtc_chat_send_btn:
                sendMsg();
                break;
            case R.id.web_rtc_video_glsv:
                webRtcChatListLv.setVisibility(View.VISIBLE);
                break;
            case R.id.web_rtc_case_place_ll:

                break;
            case R.id.web_rtc_case_place_iv:
                Lg.i(TAG, "---");
                if (webRtcMap.getVisibility() == View.VISIBLE) {
//                    sendAddressMsg();
                    hideMap();
                } else {
                    showMap();
                }
                break;
            case R.id.web_rtc_switch_camera_iv:
                mVideoRoomPlugin.switchCamera();
                break;
            default:
        }
    }

    private void showMap() {
        webRtcMap.setVisibility(View.VISIBLE);
//        webRtcCasePlaseIv.setImageResource(R.mipmap.btn_ok);
    }

    private void hideMap() {
//        webRtcCasePlaseIv.setImageResource(R.mipmap.poi_marker_pressed);
        webRtcMap.setVisibility(View.GONE);
    }

    private void sendAddressMsg() {
        String latlng = Constant.SEND_LATLNG_MSG_TAG_START + mLat + ","
                + mLng + Constant.SEND_LATLNG_MSG_TAG_END;
        String address = Constant.SEND_ADDRESS_MSG_TAG_START + webRtcCasePlaceEt.getText().toString().trim()
                + Constant.SEND_ADDRESS_MSG_TAG_END;
        mWebRtcPresenter.sendChatMsg(latlng, mIsTest);
        mWebRtcPresenter.sendChatMsg(address, mIsTest);
    }

    private void recycleCall(){
        mVideoRoomPlugin.destroy();
    }

    private void startCall() {
        mVideoRoomPlugin.initializeMediaContext(WebRtcActivity.this);
        mVideoRoomPlugin.start();
    }

    private void stopCall() {
        mUnPublished = true;
        finish();
    }

    private void showExitDialog() {
        VersionUpdataHelper.CustomDialog.Builder builder = new VersionUpdataHelper.CustomDialog.Builder(this);
        builder.setMessage("是否关闭本次视频通信？");
        builder.setPositiveButton("结束", (dialog, which) -> {
            stopCall();
            dialog.dismiss();
        });
        builder.setNegativeButton("不结束", (dialog, which) -> dialog.dismiss());
        VersionUpdataHelper.CustomDialog dialog = builder.create();
        dialog.setCancelable(true);
        dialog.show();
    }

    private void chooseLocalImage() {
        UploadHelper.selectImageFromStore(this, UploadHelper.IMAGE_FROM_LOCAL);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == UploadHelper.IMAGE_FROM_LOCAL) {
                String path = UploadHelper.getImageAbsolutePath(this, data.getData());
                mWebRtcPresenter.sendImageMsg(path);
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public void onBackPressed() {
        showExitDialog();
    }

    private void sendMsg() {
        mSendLastMsg = webRtcChatEt.getText().toString().trim();
        if (TextUtils.isEmpty(mSendLastMsg)) {
            showShortToast(getString(R.string.please_input_text));
            return;
        }
        mWebRtcPresenter.sendChatMsg(mSendLastMsg, mIsTest);
    }

    private void addChatListEntity(ChatMsgTextEntity entity) {
        mChatMsgTextEntityList.add(entity);
        runOnUiThread(() -> mChatListAdapter.notifyDataSetChanged());
    }

    private void showReconnectJaunsDialog(){
        showInteractionDialog(
                "视频连接出现异常，是否立即重新连接？", false,
                "重连", "退出",
                (dialog, which) -> {
                    recycleCall();
                    initVideoRoom();
                    dialog.dismiss();
                },
                (dialog, which) -> {
                    stopCall();
                    dialog.dismiss();
                });
    }

    @Override
    @Subscribe
    public void onEventMainThread(EventBusMessage eventBusMessage) {
        if (eventBusMessage.getCode() == EventBusHelper.JANUS_RECEIVE_HANG_UP) {
            if (!eventBusMessage.getMessage().equals(Constant.JANUS_HANGUP_ICE_FAILED)) {
                return;
            }
            runOnUiThread(() -> {
                Lg.i(TAG, "---hangup===" + Constant.JANUS_HANGUP_ICE_FAILED);
                showReconnectJaunsDialog();
            });
        }else if (eventBusMessage.getCode() == EventBusHelper.JANUS_RECEIVE_UNPUBLISHED){

        }else {
            super.onEventMainThread(eventBusMessage);
        }
    }

    @Override
    public void finish() {
        recycleCall();
        mWebRtcPresenter.stopChat();
        super.finish();
    }

    @Override
    public void onPause() {
        super.onPause();
        webRtcMap.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        webRtcMap.onDestroy();
    }

    @Override
    public void onResume() {
        super.onResume();
        webRtcMap.onResume();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        webRtcMap.onSaveInstanceState(outState);
    }

    @Override
    public void responseError(int code, String msg) {

    }

    @Override
    public void requestFailure(Throwable t) {
        super.requestFailure(t);
    }

    @Override
    public void createChatSuccess(String id) {
        mId = id;
    }

    @Override
    public void chatConnectionStart() {
//        mWebRtcPresenter.sendChatMsg(SpHelper.getInstance().getUserName()+" "+Constant.CHAT_HEART,
//                mIsTest);
    }

    @Override
    public void chatConnectionStop() {
        showShortToast("退出聊天室");
    }

    @Override
    public void chatConnectionError() {
    }

    @Override
    public void chatHasNewMsg(ChatMsgTextEntity msgTextEntity, String filePath) {
        if (msgTextEntity.getEvent().equals(Constant.CHAT_LOGIN)){
//            showShortToast(getString(R.string.have_the_reply));
        }
        if (msgTextEntity.getEvent().contains(Constant.CHAT_SELECTION)){
            switch (msgTextEntity.getBody().getText().trim()){
                case "0":
                    mUploadLatlngAble = 0;
                    break;
                case "1":
                    mUploadLatlngAble = 1;
                    break;
                case "2":
                    mUploadLatlngAble = 2;
                    break;
                default:
            }
            return;
        }
        if (!TextUtils.isEmpty(msgTextEntity.getBody().getText()) &&
                msgTextEntity.getBody().getText().contains(Constant.SEND_IMAGE_MSG_TAG_END) &&
                msgTextEntity.getFrom().equals(SpHelper.getInstance().getUserId())) {
            msgTextEntity.getBody().setText("照片材料“" + new File(filePath).getName() + "”发送成功");
        }
        if (null == filePath && msgTextEntity.getBody().getText() != null){
            addChatListEntity(msgTextEntity);

        }
    }

    @Override
    public void chatSendMsgSuccess(ChatMsgTextEntity msgTextEntity) {
        webRtcChatEt.setText("");
    }

    @Override
    public void chatSendMsgError(String msg, Throwable e) {
    }

    @Override
    public boolean isTest() {
        return mIsTest;
    }

    @Override
    public void chatIsLogout() {
//        stopCall(false);
    }

    @Override
    public String getCallType() {
        return mVideoType;
    }

    @Override
    public void onMyLocationChange(Location location) {
        UploadLocationService.startUploadLocation(this,
                location.getLongitude(), location.getLatitude(), "");
    }

    private class ChatListAdapter extends ArrayAdapter {

        public ChatListAdapter(@NonNull Context context, @LayoutRes int resource) {
            super(context, resource);
        }

        @Override
        public int getCount() {
            return mChatMsgTextEntityList.size();
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            View view;
            view = LayoutInflater.from(getContext()).inflate(R.layout.item_video_chat_left, null);
            TextView timeTv = view.findViewById(R.id.item_video_chat_time);
            TextView msgLeftTv = view.findViewById(R.id.item_video_chat_msg_left);
            TextView msgRightTv = view.findViewById(R.id.item_video_chat_msg_right);

            ChatMsgTextEntity entity = mChatMsgTextEntityList.get(position);
            if (entity.getEvent().equals(Constant.CHAT_LOGIN)) {
                msgLeftTv.setVisibility(View.VISIBLE);
                if (!entity.getFrom().equals(SpHelper.getInstance().getUserId())) {
                    if (entity.getFrom().equals("system")) {
                        Lg.i(TAG, "---system===" + entity.getBody().getText());
                        msgLeftTv.setText(entity.getBody().getText());
                    }
//                    else {
//                        msgLeftTv.setText("系统助理：\n" + entity.getBody().getNickName() + "为您服务，请您语音说明情况。如果不方面说话，也可以用文字表达。");
//                    }
                }
            } else if (entity.getEvent().equals(Constant.CHAT_MESSAGE) || entity.getEvent().equals(Constant.CHAT_TEST)) {
                if (SpHelper.getInstance().getUserId().equals(entity.getBody().getSender())) {
                    msgRightTv.setVisibility(View.VISIBLE);
                    msgRightTv.setText(entity.getBody().getText());
                    timeTv.setText(Utils.dateToTime(entity.getBody().getTime()));
                    timeTv.setVisibility(View.VISIBLE);
                } else {
                    msgLeftTv.setVisibility(View.VISIBLE);
                    msgLeftTv.setText(entity.getBody().getText());
                    timeTv.setText(entity.getBody().getTime());
                    timeTv.setVisibility(View.VISIBLE);
                }
            }
            return view;
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode){
            case KeyEvent.KEYCODE_VOLUME_UP:
                mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
                return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}
